package md;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * La clase CuentaMD maneja los datos de la tabla cuenta de la BDD
 *
 * @author Jose Luis Torres
 * @version 1.0
 */
public class CuentaMD {

    private int idCuenta;
    private int codigoUsuario;
    private String nombreCuenta;
    private int idSistema;
    private int idContrasena;

    /**
     * Constructor vacio. Settea los atributos a los valores por defecto
     */
    public CuentaMD() {
        this.idCuenta = -1;
        this.codigoUsuario = -1;
        this.nombreCuenta = "";
        this.idSistema = -1;
        this.idContrasena = -1;
    }

    /**
     * Metodo para ingresar una nueva cuenta en el sistema.
     *
     * @return Devuelve TRUE si es que se ingresa correctamente el registro en
     * la BDD.
     */
    public boolean ingresarCuenta() {
        boolean retorno = false;
        String sql = "";
        if (this.codigoUsuario != -1 && !this.nombreCuenta.equals("")) {
            sql = "INSERT INTO \"Cuenta\" "
                    + "(\"idCuenta\", \"codigoUsuario\", \"nombreCuenta\", \"idSistema\", \"idContrasena\")"
                    + " VALUES (" + CuentaMD.genCodigoCuenta()
                    + ", " + this.codigoUsuario
                    + ", '" + this.nombreCuenta
                    + "', " + this.idSistema
                    + ", " + this.idContrasena + ")";

            System.out.println(sql);
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                if (stmt.executeUpdate(sql) > 0) {
                    retorno = true;
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * Metodo para modificar una cuenta en el sistema.
     *
     * @return Devuelve TRUE si es que se modifica correctamente el registro en
     * la BDD.
     */
    public boolean modificarCuenta() {
        boolean retorno = false;
        String sql = "";
        if (this.codigoUsuario != -1 && !this.nombreCuenta.equals("")) {
            sql = "UPDATE \"Cuenta\" "
                    + "SET \"nombreCuenta\" = '" + this.nombreCuenta + "',"
                    + "\"idSistema\" = " + this.idSistema + ", "
                    + "\"idContrasena\" = " + this.idContrasena
                    + " WHERE \"idCuenta\" = " + this.idCuenta;

            //System.out.println(sql);
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                if (stmt.executeUpdate(sql) > 0) {
                    retorno = true;
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * Metodo para eliminar una cuenta en el sistema.
     *
     * @return Devuelve TRUE si es que se elimina correctamente el registro en
     * la BDD.
     */
    public boolean eliminarCuenta() {
        boolean retorno = false;
        String sql = "";
        System.out.println(this.idSistema + " y " + this.nombreCuenta);
        getDatosCuenta();

        if (this.codigoUsuario != -1 && !this.nombreCuenta.equals("")) {
            sql = "DELETE FROM \"Cuenta\" "
                    + "WHERE \"idCuenta\" = " + this.idCuenta;
            //System.out.println(sql);
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                if (stmt.executeUpdate(sql) > 0) {
                    retorno = true;
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * Muestra las TODAS cuentas disponible del usuario.
     *
     * @return Duevuelve una lista con TODAS las cuentas disponibles par el
     * usuario
     */
    public List verCuenta(int c) {
        List<String[]> retorno = new ArrayList<String[]>();

        String sql = "SELECT \"nombreSistema\", \"contrasena\", \"nombreCuenta\", \"codigoCategoria\", \"fechaIngreso\""
                + "FROM \"Cuenta\", \"Sistema\", \"Contrasena\""
                + "WHERE \"codigoUsuario\" ="+ c+ "AND"
                + "\"Cuenta\".\"idSistema\" = \"Sistema\".\"idSistema\" AND"
                + " \"Cuenta\".\"idContrasena\" = \"Contrasena\".\"idContrasena\""
                + "ORDER BY \"idCuenta\"";
        try {
            Statement stmt = Db.getDb().getConexion().createStatement();
            ResultSet rset = stmt.executeQuery(sql);
            while (rset.next()) {

                String[] arr = {rset.getString("nombreCuenta"),
                    rset.getString("contrasena"),      
                    rset.getString("nombreSistema"),
                rset.getString("codigoCategoria"),
                rset.getString("fechaIngreso")};

                retorno.add(arr);
            }
            System.out.println(retorno);
            stmt.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return retorno;
    }

    /**
     * Verifica que no exista la combinacion de cuenta y sistema en la BDD.
     *
     * @return Devuelve TRUE si es que existe la combinacion.
     */
    public boolean verificarCuenta() {
        boolean retorno = false;
        String sql;
        if (this.idSistema != -1 && !this.nombreCuenta.equals("")) {
            sql = "SELECT 1 "
                    + "FROM \"Cuenta\""
                    + "WHERE \"idSistema\" = '" + this.idSistema + "' "
                    + "AND \"nombreCuenta\" = '" + this.nombreCuenta + "'";
            //System.out.println(sql);
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                ResultSet rset = stmt.executeQuery(sql);
                if (rset.next()) {
                    retorno = true;
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * Verifica si un sistema existe o no en la BBD.
     *
     * @return Devuelve TRUE si el sistema existe en la BDD.
     */
    public boolean verificarSistema() {
        boolean retorno = false;
        String sql;
        if (this.idSistema != -1) {
            sql = "SELECT \"idSistema\" "
                    + "FROM \"Sistema\" "
                    + "WHERE \"idSistema\" = " + this.idSistema;
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                ResultSet rset = stmt.executeQuery(sql);
                while (rset.next()) {
                    retorno = true;
                    //System.out.println(rset.getString("idSistema"));
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * Calcula el idCuenta que corresponde en la BDD
     *
     * @return Devuelve un entero con el codigo que corresponde en la secuencia
     */
    public static int genCodigoCuenta() {
        int retorno = -1;
        String sql = "SELECT MAX(\"idCuenta\") + 1 "
                + "FROM \"Cuenta\"";
        try {
            Statement stmt = Db.getDb().getConexion().createStatement();
            ResultSet rset = stmt.executeQuery(sql);
            while (rset.next()) {
                retorno = rset.getInt(1);
            }
            stmt.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return retorno;
    }

    /**
     * Setea los atributos del objeto con la info de la BDD, de acuerdo al id
     * del sistema y al nombre de cuenta que se setea externamente. Es decir
     * busca por id del sistema y nombre de cuenta y setea el resto de
     * atributos.
     *
     * @return Devuelve TRUE si es que se encuentra el objeto en la BDD. FALSE
     * caso contrario.
     */
    public boolean getDatosCuenta() {
        boolean retorno = false;
        if (this.idSistema != -1 && !this.nombreCuenta.equals("")) {
            String sql = "SELECT \"idCuenta\", \"codigoUsuario\", \"idSistema\", \"idContrasena\" "
                    + "FROM \"Cuenta\" "
                    + "WHERE \"idSistema\" = '" + this.idSistema + "' "
                    + "AND \"nombreCuenta\" like '%" + this.nombreCuenta + "%'";
            //System.out.println(sql);
            try {
                Statement stmt = Db.getDb().getConexion().createStatement();
                ResultSet rset = stmt.executeQuery(sql);
                if (rset.next()) {
                    retorno = true;
                    this.idCuenta = rset.getInt("idCuenta");
                    this.codigoUsuario = rset.getInt("codigoUsuario");
                    this.idSistema = rset.getInt("idSistema");
                    this.idContrasena = rset.getInt("idContrasena");
                }
                stmt.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return retorno;
    }

    /**
     * *************************************
     * Getters & Setters
     **************************************
     */
    public int getCodigoUsuario() {
        return codigoUsuario;
    }

    public int getIdContrasena() {
        return idContrasena;
    }

    public int getIdCuenta() {
        return idCuenta;
    }

    public int getIdSistema() {
        return idSistema;
    }

    public String getNombreCuenta() {
        return nombreCuenta;
    }

    public void setCodigoUsuario(int codigoUsuario) {
        this.codigoUsuario = codigoUsuario;
    }

    public void setIdContrasena(int idContrasena) {
        this.idContrasena = idContrasena;
    }

    public void setIdCuenta(int idCuenta) {
        this.idCuenta = idCuenta;
    }

    public void setIdSistema(int idSistema) {
        this.idSistema = idSistema;
    }

    public void setNombreCuenta(String nombreCuenta) {
        this.nombreCuenta = nombreCuenta;
    }
}
